/*
 * This file is part of algowala.
 *
 * algowala is copyright (c) 2012 Jagannathan Sampath <algowala@jagernot.com>
 *
 * algowala is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * algowala is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with algowala.  If not, see <http://www.gnu.org/licenses/>.
 *
*/

#include "stock.h"
#include "ansi_color_codes.h"
#include "random.h"
#include "bot.h"
#include <list>
#include <iostream>
#include <algorithm>

using namespace std;

stock::stock (const std::string& sym, const std::string& com, double _price, double _volatility, int _volume, int _vol_volatility, int _n_times, int _m_secs, double now) : symbol (sym), company (com), price (_price, _volatility), volume (_volume, _vol_volatility) {
    
  n_times = _n_times;
  m_secs = _m_secs;
  
  calc_update_time ();
  last_change_time = now;
  
  num_ticks = 1;
  tick_data.push_back (tick_data_t (price.value, volume.value, 0));
  start = end = tick_data.begin ();
  startn = endn = 0;
  
  rnd<float> rd (0.25, 1);
  clr = color (rd(), rd(), rd());
  
}

stock::stock (const stock& s) {
  operator= (s);
}

stock& stock::operator= (const stock& s) {
  
  if (&s != this) {
    
    symbol = s.symbol;
    company = s.company;
    
    price = s.price;
    volume = s.volume;
    
    n_times = s.n_times;
    m_secs = s.m_secs;
    
    update_time = s.update_time;
    
    last_change_time = s.last_change_time;
    num_ticks = s.num_ticks;
    
    tick_data.clear ();
    copy (s.tick_data.begin (), s.tick_data.end (), back_inserter (tick_data));
    start = end = tick_data.begin ();
    startn = s.startn;
    endn = s.endn;
    for (int i = 0; i < startn; ++i) ++start;
    for (int i = 0; i < endn; ++i) ++end;
    clr = s.clr;

  }
  return *this;
}

int stock::tick (double now) { // try to move price & volume of stock   
  int ticked = 0;
  double elapsed = now - last_change_time; // time since last change
  while (elapsed > update_time) {
    elapsed -= update_time;
    last_change_time += update_time;
    price.move (); // move price
    volume.move (); // move volume
    tick_data.push_back (tick_data_t (price.value, volume.value, last_change_time));
    ++num_ticks;
    ticked = 1;
  }
  if (ticked) last_change_time += elapsed;
  return ticked;
}
